package com.tensquare.base.service.impl;

import cn.hutool.core.util.StrUtil;
import com.tensquare.base.dao.LabelDao;
import com.tensquare.base.pojo.Label;
import com.tensquare.base.service.LabelService;
import entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import util.IdWorker;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

@Service
public class LabelServiceImpl implements LabelService {
    @Autowired
    private LabelDao labelDao;
    @Autowired
    private IdWorker idWorker;
    /**
     * 1.查询所有的标签
     * @return 返回所有的标签信息
     */
    @Override
    public List<Label> findAll() {
        return labelDao.findAll();
    }

    /**
     * 2.查询所有推荐的标签
     * @return 返回所有的推荐标签
     */
    @Override
    public List<Label> findByRecommend() {
        //2.1设置查询条件
        Label recommend = new Label();
        recommend.setRecommend("1");
        Example<Label> example = Example.of(recommend);
        //2.2查询
        return labelDao.findAll(example);
    }

    /**
     * 3.查询所有有效的标签
     * @return 返回所有有效的标签
     */
    @Override
    public List<Label> findByState() {
        //3.1设置查询的条件
        Label state = new Label();
        state.setState("1");
        Example<Label> example = Example.of(state);
        //3.2开始查询
        return labelDao.findAll(example);
    }

    /**
     * 4.根据标签id查询标签信息
     * @param labelId 标签id
     * @return 返回对应的标签信息
     */
    @Override
    public Label findOne(String labelId) {
        return labelDao.findById(labelId).get();
    }

    /**
     * 5.添加标签信息
     * @param label 要添加的标签
     */
    @Override
    public void add(Label label) {
        //5.1设置标签id
        long nextId = idWorker.nextId();
        label.setId(nextId + "");
        //5.2添加标签信息
        labelDao.save(label);
    }

    /**
     * 6.根据id和标签信息修改标签
     * @param label     修改的标签信息
     */
    @Override
    public void update(Label label) {
        labelDao.save(label);
    }

    /**
     * 7.根据标签id删除标签信息
     * @param labelId 标签信息
     */
    @Override
    public void delete(String labelId) {
        labelDao.deleteById(labelId);
    }

    /**
     * 8.条件查询
     * @param label 查询条件
     * @return  查询结果
     */
    @Override
    public List<Label> search(Label label) {
        return labelDao.findAll(createSpecification(label));
    }

    /**
     * 创建查询条件
     * @param label 查询条件
     * @return  创建好的查询条件
     */
    private Specification<Label> createSpecification(Label label) {
        return new Specification<Label>() {
            @Override
            public Predicate toPredicate(Root<Label> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //8.1定义查询条件的集合
                List<Predicate> predicateList = new ArrayList<>();
                //8.2向集合中添加查询条件
                if (label != null){
                    if (StrUtil.isNotBlank(label.getLabelname())){      //标签名模糊查询
                        predicateList.add(criteriaBuilder.like(root.get("labelname").as(String.class),"%"+label.getLabelname()+"%"));
                    }
                    if (StrUtil.isNotBlank(label.getState())){      //状态等值查询
                        predicateList.add(criteriaBuilder.equal(root.get("state").as(String.class),label.getState()));
                    }
                    if (StrUtil.isNotBlank(label.getRecommend())){  //是否热点的等值查询
                        predicateList.add(criteriaBuilder.equal(root.get("recommend").as(String.class),label.getRecommend()));
                    }
                }
                //8.3定义泛型数组
                Predicate[] pre = new Predicate[predicateList.size()];
                //8.4将条件集合转换为条件数组
                Predicate[] predicates = predicateList.toArray(pre);
                //8.5将查询条件数组返回
                return criteriaBuilder.and(predicates);
            }
        };
    }

    /**
     * 9.分页查询
     * @param page  当前页
     * @param size  总页数
     * @param label 查询条件
     * @return  返回的分页查询结果
     */
    @Override
    public PageResult<Label> search(int page, int size, Label label) {
        //9.1分页条件查询
        Page<Label> labelPage = labelDao.findAll(createSpecification(label), PageRequest.of(page, size));
        //9.2构建返回的结果类
        return new PageResult<>(labelPage.getTotalElements(),labelPage.getContent());
    }
}
